#include <iostream>
#include <climits>
#include <cstdio>
using namespace std;
template <typename T>
class PriorityQueue{
public:
int parent(int ind){
return ind>>1;
}
int left(int ind){
return ind<<1;
}
int right(int ind){
return (ind<<1)+1;
}
T* array(void){
return arr;
}
void swap(int i, int j){
i--; j--;
assert(i>=0 && j>=0);
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
void MaxHeapify(int ind){
int l=left(ind), r=right(ind), largest;
assert(ind>=0 && l>=0 && r>=0);
if(l<=this->heap_size && this->arr[l-1]>this->arr[ind-1]) largest=l;
else largest=ind;
if(r<=this->heap_size && this->arr[r-1]>this->arr[largest-1]) largest=r;
if(largest!=ind){
swap(ind, largest);
MaxHeapify(largest);
}
}
void Build_Max_Heap(void){
for(int i=this->heap_size/2; i>=1; --i){
MaxHeapify(i);
}
}
void HeapSort(void){
Build_Max_Heap();
int prev_size=this->heap_size;
for(int i=this->heap_size; i>=2; --i){
swap(1, i);
this->heap_size--;
MaxHeapify(1);
}
this->heap_size=prev_size;
}
T Heap_MaxiMum(void){
return this->arr[0];
}
T Heap_Extract_Max(void){
if(this->heap_size<1){
perror("Heap Underflow");
exit(1);
}
T max=arr[0];
arr[0]=arr[heap_size-1];
T* arr2=new T[heap_size-1];
heap_size--;
for(int i=0; i<heap_size; ++i){
arr2[i]=arr[i];
}
delete arr;
arr=arr2;
MaxHeapify(1);
return max;
}
void Heap_Increase_Key(int i, T key){
if(key<arr[i-1]){
perror("New key is smaller then present one.");
exit(1);
}
arr[i-1]=key;
while(i>1 && arr[parent(i)-1]<arr[i-1]){
swap(i, parent(i));
i=parent(i);
}
}
void Max_Heap_Insert(T key){
T* arr2=new T[this->heap_size+1];
for(int i=0; i<this->heap_size; ++i) arr2[i]=arr[i];
delete arr;
arr=arr2;
this->heap_size++;
arr[heap_size-1]=-INT_MAX;
Heap_Increase_Key(heap_size, key);
}
void print(void){
for(int i=0; i<heap_size-1; ++i){
cout<<arr[i]<<", ";
}
cout<<arr[heap_size-1]<<endl;
}
PriorityQueue(T* _arr, int _heap_size): heap_size(_heap_size){
arr=new T[heap_size];
for(int i=0; i<heap_size; ++i) arr[i]=_arr[i];
Build_Max_Heap();
}
~PriorityQueue(){
delete arr;
}
private:
T* arr;
int heap_size;
};
int main(void){
int arr[]={15, 13, 9, 5, 12, 8, 7, 4, 0 ,6, 2, 1};
int size=sizeof(arr)/sizeof(int);
PriorityQueue<int>* pqueue=new PriorityQueue<int>(arr, size);
cout<<"Max: "<<pqueue->Heap_Extract_Max()<<endl;
pqueue->print();
pqueue->Heap_Increase_Key(5, 30);
cout<<"increase key i=5, key=30\n";
pqueue->print();
cout<<"insert key key=15\n";
pqueue->Max_Heap_Insert(15);
pqueue->print();
cout<<"sort Queue\n";
pqueue->HeapSort();
pqueue->print();
delete pqueue;
}